#ifndef ABCCompositor_C__
#define ABCCompositor_C__

#include "Compositor.h"

template<class PEA,class TRAITS>
	void BaseCompositor<PEA,TRAITS>::addItem(PEA* newItem)
{
	m_ItemCol.push_back(newItem);
}

template<class PEA,class TRAITS>
	void BaseCompositor<PEA,TRAITS>::clear()
{
	for (tItemVec::iterator iDx = m_ItemCol.begin(); 
		iDx < m_ItemCol.end(); iDx++)
	{
		PEA*	tmp = *iDx;
		delete (tmp);
	}

	m_ItemCol.clear();
}


	//TODO	what happens when you return POD? only the last int would be returned...
	//maybe adding traits for this level too...

template<class PEA,void (PEA::*funcPtr)(),class TRAITS>
	void ABCCompositor<PEA,funcPtr,TRAITS>::IterateThrough()
{
	for (tItemVec::iterator iDx = m_ItemCol.begin(); 
		iDx < m_ItemCol.end(); iDx++)
	{
		CALL_MEMBER_FN(*(*iDx),funcPtr)();
	}
}

template < class ARG1 , class PEA, void (PEA::*funcPtr)(ARG1& Arg1),class TRAITS >
	void ABCCompositor_0Ret1ArgRef<ARG1 , PEA , funcPtr,TRAITS>::IterateThrough(ARG1 &Arg1)	
{
	for (tItemVec::iterator iDx = m_ItemCol.begin(); 
		iDx < m_ItemCol.end(); iDx++)
	{
		CALL_MEMBER_FN(*(*iDx),funcPtr)(Arg1);
	}
}

template < class ARG1 , class PEA, void (PEA::*funcPtr)(ARG1* Arg1),class TRAITS >
	void ABCCompositor_0Ret1ArgPtr<ARG1 , PEA , funcPtr,TRAITS>::IterateThrough(ARG1 *Arg1)	
{
	for (tItemVec::iterator iDx = m_ItemCol.begin(); 
		iDx < m_ItemCol.end(); iDx++)
	{
		CALL_MEMBER_FN(*(*iDx),funcPtr)(Arg1);
	}
}

template <class RET , class PEA , RET (PEA::*funcPtr)(),class TRAITS>
	RET ABCCompositor_1Ret0Arg<RET,PEA,funcPtr,TRAITS>::IterateThrough()
{
	RET retVal;
	for (tItemVec::iterator iDx = m_ItemCol.begin(); 
		iDx < m_ItemCol.end(); iDx++)
	{
		TRAITS::returnModifier(retVal,CALL_MEMBER_FN(*(*iDx),funcPtr)());
	}
	
	return retVal;
}

template <class RET , class PEA , RET& (PEA::*funcPtr)(),class TRAITS>
	RET& ABCCompositor_1RetRef0Arg<RET,PEA,funcPtr,TRAITS>::IterateThrough()
{
	RET* retVal = new RET;
	for (tItemVec::iterator iDx = m_ItemCol.begin(); 
		iDx < m_ItemCol.end(); iDx++)
	{
		TRAITS::returnModifier(retVal,CALL_MEMBER_FN(*(*iDx),funcPtr)());
	}
	
	return *retVal;
}

template <class RET , class PEA , RET* (PEA::*funcPtr)(),class TRAITS>
	RET* ABCCompositor_1RetPtr0Arg<RET,PEA,funcPtr,TRAITS>::IterateThrough()
{
	RET* retVal = new RET;
	for (tItemVec::iterator iDx = m_ItemCol.begin(); 
		iDx < m_ItemCol.end(); iDx++)
	{
		TRAITS::returnModifier(retVal,CALL_MEMBER_FN(*(*iDx),funcPtr)());
	}
	
	return retVal;
}
template <class RET , class ARG1, class PEA,RET (PEA::*funcPtr)(ARG1& Arg1),class TRAITS>
	RET ABCCompositor_1Ret1Arg<RET,ARG1,PEA,funcPtr,TRAITS>::IterateThrough(ARG1& Arg1)
{
	RET retVal;
	for (tItemVec::iterator iDx = m_ItemCol.begin(); 
		iDx < m_ItemCol.end(); iDx++)
	{
		TRAITS::returnModifier(retVal,CALL_MEMBER_FN(*(*iDx),funcPtr)(Arg1));
	}
	return retVal;
}

template <class RET , class ARG1, class PEA,RET& (PEA::*funcPtr)(ARG1& Arg1),class TRAITS>
	RET& ABCCompositor_1RetRef1Arg<RET,ARG1,PEA,funcPtr,TRAITS>::IterateThrough(ARG1& Arg1)
{
	RET* retVal = new RET;
	for (tItemVec::iterator iDx = m_ItemCol.begin(); 
		iDx < m_ItemCol.end(); iDx++)
	{
		TRAITS::returnModifier(*retVal,CALL_MEMBER_FN(*(*iDx),funcPtr)(Arg1));
	}
	return *retVal;
}

template <class RET , class ARG1, class PEA,RET* (PEA::*funcPtr)(ARG1& Arg1),class TRAITS>
	RET* ABCCompositor_1RetPtr1Arg<RET,ARG1,PEA,funcPtr,TRAITS>::IterateThrough(ARG1& Arg1)
{
	RET* retVal = new RET;
	for (tItemVec::iterator iDx = m_ItemCol.begin(); 
		iDx < m_ItemCol.end(); iDx++)
	{
		TRAITS::returnModifier(*retVal,CALL_MEMBER_FN(*(*iDx),funcPtr)(Arg1));
	}
	return retVal;
}

template <class RET , class ARG1, class ARG2 , class PEA,RET (PEA::*funcPtr)(ARG1& Arg1,ARG2& Arg2),class TRAITS>
	RET ABCCompositor_1Ret2Arg<RET,ARG1,ARG2,PEA,funcPtr,TRAITS>::IterateThrough(ARG1& Arg1,ARG2& Arg2)
{
	RET retVal;
	for (tItemVec::iterator iDx = m_ItemCol.begin(); 
		iDx < m_ItemCol.end(); iDx++)
	{
		TRAITS::returnModifier(retVal,CALL_MEMBER_FN(*(*iDx),funcPtr)(Arg1,Arg2));
	}

	return retVal;
}

template <class RET , class ARG1, class ARG2 , class PEA,RET& (PEA::*funcPtr)(ARG1& Arg1,ARG2& Arg2),class TRAITS>
	RET& ABCCompositor_1RetRef2Arg<RET,ARG1,ARG2,PEA,funcPtr,TRAITS>::IterateThrough(ARG1& Arg1,ARG2& Arg2)
{
	RET* retVal = new RET;
	for (tItemVec::iterator iDx = m_ItemCol.begin(); 
		iDx < m_ItemCol.end(); iDx++)
	{
		TRAITS::returnModifier(retVal,CALL_MEMBER_FN(*(*iDx),funcPtr)(Arg1,Arg2));
	}

	return *retVal;
}

template <class RET , class ARG1, class ARG2 , class PEA,RET* (PEA::*funcPtr)(ARG1& Arg1,ARG2& Arg2),class TRAITS>
	RET* ABCCompositor_1RetPtr2Arg<RET,ARG1,ARG2,PEA,funcPtr,TRAITS>::IterateThrough(ARG1& Arg1,ARG2& Arg2)
{
	RET* retVal = new RET;
	for (tItemVec::iterator iDx = m_ItemCol.begin(); 
		iDx < m_ItemCol.end(); iDx++)
	{
		TRAITS::returnModifier(retVal,CALL_MEMBER_FN(*(*iDx),funcPtr)(Arg1,Arg2));
	}

	return retVal;
}





//TODO	Check the new operator for leaks
#endif